package link.jfire.jnet.client;

import java.nio.channels.CompletionHandler;
import link.jfire.jnet.common.InternalResultContainer;
import link.jfire.jnet.common.buffer.ByteBuf;
import link.jfire.jnet.common.decodec.FrameDecodec;
import link.jfire.jnet.common.exception.BufNotEnoughException;
import link.jfire.jnet.common.exception.LessThanProtocolException;
import link.jfire.jnet.common.exception.NotFitProtocolException;
import link.jfire.jnet.common.handler.DataHandler;

public class ClientReadCompleter implements CompletionHandler<Integer, AioClient>
{
    private DataHandler[] handlers;
    private FrameDecodec  frameDecodec;
                          
    public ClientReadCompleter(FrameDecodec frameDecodec, DataHandler... handlers)
    {
        if (handlers == null || handlers.length == 0)
        {
            throw new RuntimeException("参数不能为空");
        }
        this.handlers = handlers;
        this.frameDecodec = frameDecodec;
    }
    
    @Override
    public void completed(Integer result, AioClient aioClient)
    {
        if (result == -1)
        {
            // 调用一个具体的方法将所有的future销毁
            aioClient.close(null);
            return;
        }
        ByteBuf<?> ioBuf = aioClient.ioBuf;
        ioBuf.addWriteIndex(result);
        Object decodeResult = null;
        ByteBuf<?> buf = null;
        do
        {
            try
            {
                decodeResult = buf = frameDecodec.decodec(ioBuf);
                if (decodeResult != null)
                {
                    ClientInternalResult internalResult = InternalResultContainer.buildClient(decodeResult, aioClient, 0);
                    for (int i = 0; i < handlers.length;)
                    {
                        decodeResult = handlers[i].handle(decodeResult, internalResult);
                        if (i == internalResult.getIndex())
                        {
                            i++;
                            internalResult.setIndex(i);
                        }
                        else
                        {
                            i = internalResult.getIndex();
                        }
                    }
                    if (decodeResult != buf)
                    {
                        buf.release();
                    }
                    aioClient.popOneFuture(decodeResult);
                }
                if (ioBuf.remainRead() == 0)
                {
                    aioClient.readAndWait();
                    return;
                }
            }
            catch (NotFitProtocolException e)
            {
                aioClient.close(e);
                return;
            }
            catch (BufNotEnoughException e)
            {
                ioBuf.ensureCapacity(e.getNeedSize());
                aioClient.continueRead();
                return;
            }
            catch (LessThanProtocolException e)
            {
                aioClient.readAndWait();
                return;
            }
            catch (Exception e)
            {
                aioClient.close(e);
                return;
            }
        } while (decodeResult != null);
        aioClient.readAndWait();
    }
    
    @Override
    public void failed(Throwable exc, AioClient aioClient)
    {
        // 调用一个具体的方法将所有的future销毁
        aioClient.close(exc);
    }
    
}
